/***************************************************************************
 *   mgpi_compmdl.c - Components Model Definitions                         *
 *   Copyright (C) 2008 by cmaster.matso                                   *
 *   cmaster.matso@gmail.com                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "mgpi_compmdl.h"

static cont_t *s_pRootContainer = NULL;                                         /** root container (main framework resources container) */

/**
 * Adds a component to given container or to the root one (if the givem is NULL).
 */
static void s_addComponent(cont_t *ct, comp_t *cp) {
    if (ct && cp) {
        cp->parent = (void *) ct;
        ct->comp_num++;

        /* TODO: add to components list... */

    } else if (cp) {
        if (s_pRootContainer) {
            cp->parent = (void *) s_pRootContainer;
            s_pRootContainer->comp_num++;

            /* TODO: add to components list... */

        } else {
            MGPI_PostMessagef("%s: first make call to 'MGPI_InitContainer(NULL)'", __FUN__);
            ENGINE_Exit();
            exit(EXIT_FAILURE);
        }
    } else {
        MGPI_PostMessagef("%s: given component is a null pointer", __FUN__);
        ENGINE_Exit();
        exit(EXIT_FAILURE);
    }
    return;
}

/**
 * Standard component-getter routine. Gets a component for the given container
 * (or the root one if NULL) by the given ID.
 */
static comp_t *s_getComponent(cont_t *ct, int id) {
    comp_t *cp = NULL;

    /* TODO: get component from list... */

    return cp;
}

/**
 * Standard component-disposer routine. Removes a component of the given ID
 * from the given container (or form the root one if NULL).
 */
static void s_removeComponent(cont_t *ct, int id) {

    /* TODO: remove component from list... */

   return;
}

/* TODO: the same for containers... */

/**
 * Gets the root container (framework internal usage only).
 */
cont_t *MGPI_GetRootContainer(void) {
    return s_pRootContainer;
}

/**
 * Initializes given container, or the root one (if given is NULL), to default values.
 */
void MGPI_InitContainer(cont_t *ct) {
    if (ct) {
        ct->comp_array = NULL;
        ct->comp_list.next = NULL;
        ct->comp_list.prev = NULL;
        ct->cont_array = NULL;
        ct->cont_list.next = NULL;
        ct->cont_list.prev = NULL;
        ct->comp_num = 0;
        ct->cont_num = 0;
        ct->addComponent = s_addComponent;
        ct->getComponent = s_getComponent;
        ct->removeComponent = s_removeComponent;

        /* TODO: and for the containers... */

    } else if (!s_pRootContainer) {
        s_pRootContainer = (cont_t *) calloc(1, sizeof (cont_t));
        MGPI_CollectGarbage(s_pRootContainer);

        s_pRootContainer->addComponent = s_addComponent;
        s_pRootContainer->getComponent = s_getComponent;
        s_pRootContainer->removeComponent = s_removeComponent;

        /* TODO: and for the containers... */

    }
    return;
}

/**
 * Gets root container's component (for event handling usage).
 */
comp_t *MGPI_GetRootComponent(void) {
    return (s_pRootContainer) ? &s_pRootContainer->component : NULL;
}
